In distributed computing environments such as cloud computing, users may use multiple server-based computational resources via a network. In such environments and other computing environments generally, hierarchical organizations of data may be represented and manipulated by systems, such as, file systems, database schemas, compilers, eXtensible Markup Language (XML), HyperText Markup Language (HTML), Electronic data interchange (EDI), relational data, any type of user-defined structure, or a proprietary structure a company or organization may use. Application programming interfaces (APIs) may be used to access services. In distributed computing environments, each cloud may have different API calls. Hierarchical data vendors may offer libraries that export API calls that deal with low-level details of hierarchical structure organizations, with such calls being referred to as canonical API calls. These calls are orthogonal and may create a basis for building the next level of functionality. These APIs may be complicated and may have a steep learning curve to master their functionality. The difficulties in using the foregoing libraries are the result of complex interactions among the canonical APIs. For example, in order to access certain elements in a XML tree using Document Object Model (DOM) API, the tree may be loaded in memory and a handle to the structure that represents this tree may be obtained in order to be used in subsequent API calls.
As a result of the complex dependencies among canonical APIs, software can be difficult to write. For example, even though the basic functionality of the MICROSOFT XML API and the XERCES XML API are comparable, their APIs may not be equivalent. This means that if a MICROSOFT implementation is to be replaced with the XERCES implementation, a software rewrite may be needed.
A preliminary step in designing software that manipulates hierarchical data may include writing a requirement specification. The choice of a language for this specification may also be carefully decided. If the chosen language is implementation specific and depends on the compiler used, then it may be difficult to convert such a specification to a different language. Another difficulty may include detection of possible ambiguities in the selected language because of its complex semantics.
Alternatively, if the chosen language is too formal, it may require significant efforts to translate the formal specification into a sequence of algorithmic steps implemented in a particular language. Formal methods may provide a higher level of abstraction than a series of algorithmic steps. However, problems may occur when the impedance mismatch between a formal specification and implementation languages with canonical APIs is significant. In such a case, the high level of abstraction that can be achieved in formal specifications is grounded. Not only can it be difficult to verify the implementation code against the formal specification, it may also be impractical to write a code analyzer that checks various semantic aspects of data manipulation.